package zunge.twitterdel.foursquare;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import fi.foyt.foursquare.api.FoursquareApi;
import fi.foyt.foursquare.api.Result;
import fi.foyt.foursquare.api.entities.Category;
import fi.foyt.foursquare.api.entities.CompactVenue;
import fi.foyt.foursquare.api.entities.VenuesSearchResult;

public class FSAPI {
	
	public static String[] credentials = 
			new String[]{
		 "3LH4AO0SQPFRIQEY2RTDF5ITXCLKXZWJOHWACE1K3JZ5EZCR", "4ZQPUZCC3PE20H5XQUMSNZNKTUQ2UZUYZ0ONSYBYKLUVZ4UL"
		,"NFMW4OYLBJZDHLQHOZAJN5DBFLWLSM34DKDUEDQAEKB30XXT", "K4XAJRRUG1J31EE3Y3Z2TOREO142GZ05GY30JD1PFVJK3B1P"
		,"JJDWYSOKKMGLP4TX5EVYQ21KFP5HDSLITDCJPE4JHCG4LAGM", "P2CZXMWKLP5UGUDBI5RWT5NTWG44SRDDVGAFZRVRZLISDCXP"
		,"3PVDD2BBSTGHTINZDQ13V3MMA0DSGM4ZWNKGCDGWXE2FSJVJ", "BBFJBPYZFMPZXLDPDG4VFTQFQBCESWUUQFRQBLZSZVJG2XDD"
		,"YMSN0IEDUPF43MW35V5WTSVACXJ1AIKS5C0KWAF1JSXEDMSX", "1GRCOU3AGRGVG52SGTQF5CFGVEH0INTXRCIDLG1LSNOHGGHW"
		,"XWM2TLO0QHXB2J1SGKIBCV1WX4YN3H5YKUEJ10AVT1PIZHXN", "OC40MV4Q4YISH5LR25GRM022OUTEGA3VHSB0PRI1WIMWV3VC"
		,"HDAGQJHZH4FWVXRS3FZ4DB2MKMZHTYMM1W40SX4PQYIQFKSH", "LSLL5XFYBCGVZRU3QMWVG10X0QMKR4V5TCYE50D4LRXOELEP"
		,"MUL5KLVXRODTX5OXMY0LTIIYPAO2Z0ABKIDPK3554KKPISHE", "VYQTTZ14PM0U1HGOIR0OXS5WJTZLJQUHELL2VJRMOK2FVADT"
		,"CJQYSYYR03XHHAVG5KWMEF0ASO25PLHVYEHKP2AIRXIJQWI1", "0HYHNY0WYOORLGZBLA0UMHVHKJNZQNEQMW2YALT2OWUPNBC3"
		,"CJQYSYYR03XHHAVG5KWMEF0ASO25PLHVYEHKP2AIRXIJQWI1", "0HYHNY0WYOORLGZBLA0UMHVHKJNZQNEQMW2YALT2OWUPNBC3"
	};//<customerId, customerSecret> pairs
	public static String CALLBACK_URL = "http://mcom.cs.cmu.edu";
	
	ArrayList<FoursquareApi> apis;
	
	public FSAPI() throws Exception{
		apis = new ArrayList<FoursquareApi>(credentials.length/2);
		for(int i = 0;i < credentials.length/2;++i){
			apis.add(new FoursquareApi(credentials[2*i], credentials[2*i+1], CALLBACK_URL));
		}
		
		genCategoryTree();
	}
	
	/* Use API credentials in turns */
	int curApiPtr = 0; 
	FoursquareApi getApi(){
		curApiPtr = (curApiPtr + 1) % apis.size();
		return apis.get(curApiPtr);
	}
	
	/* Handlers for Exceeding Limit */
	boolean isWaiting = false;
	static int DEFAULT_WAITING_TIME = 200;
	static int MAX_WAITING_TIME = 3600*1000;
	int curWaitingTime = DEFAULT_WAITING_TIME;
	void haveARest() throws Exception{
		System.out.println("Sleep for "+curWaitingTime);
		Thread.sleep(curWaitingTime);
		if(isWaiting){curWaitingTime = Math.max(curWaitingTime*2, MAX_WAITING_TIME);}
		isWaiting = true;
	}
	void wakeUp(){
		isWaiting = false;
		curWaitingTime = DEFAULT_WAITING_TIME;
	}
	
	public String getLocationCategory(String ll) throws Exception{
		
		Result<VenuesSearchResult> result;
		boolean repeat = false;
		while(true){
			if(repeat){System.out.println("repeat");}
			result = getApi().venuesSearch(ll, 
					null, null, null, null, null, null, null, null, null, null);
			if(result.getMeta().getCode()==200){wakeUp();break;}
			else{haveARest();repeat=true;}
		}
		
		String catName = "null";
		if(result.getResult().getVenues().length>0){
			CompactVenue venue = result.getResult().getVenues()[0];		
			if(venue.getCategories().length>0){
				catName = venue.getCategories()[0].getName();
			}
		}
		return catName;
	}
	
	/* ********** Category Service ********** */
	TreeHierarchy<String> th;
	
	public void genCategoryTree() throws Exception{
		th = new TreeHierarchy<String>("ROOT");
		
		Result<Category[]> result = getApi().venuesCategories();
		for(Category cat:result.getResult()){
			processCategory(cat);
		}
	}
	void processCategory(Category cat){
		Category[] subcats = cat.getCategories();
		
		if(subcats != null && subcats.length >0){
			for(Category subcat:subcats){
				th.addRelation(cat.getName(), subcat.getName());
				processCategory(subcat);
			}
		}
	}
	
	public String getRootCategory(String catName){
		return th.getSubRoot(catName);
	}
	public boolean isCategoryPrivate(String catName){
		return getRootCategory(catName).equals("Residences");
	}
	
	
	
	
	public static void main(String args[]){
		try{
			FSAPI fsapi = new FSAPI();
			fsapi.th.printHierarchy();
		}catch(Exception e){e.printStackTrace();}
		
	}
}
